Android Studio上Cmake的搭建与使用

您所在的位置:网站首页 cmake 合并静态库 Android Studio上Cmake的搭建与使用

Android Studio上Cmake的搭建与使用

2023-09-07 08:29| 来源: 网络整理| 查看: 265

1、什么是Cmake?

​ C/C++ 的编译文件在不同平台是不一样的。Unix 下使用 makefile 文件编译,Windows 下使用 project 文件编译。而 CMake 则是一个跨平台的编译工具,它并不会直接编译出对象,而是根据自定义的语言规则(CMakeLists.txt)生成 对应 makefile 或 project 文件,然后再调用底层的编译.

​ 谷歌从AndroidStudio2.2以上就添加了Cmake方式来编译NDK代码,相较之前复杂的NDK-BUILDE方式,Cmake则简单很多。

2、什么是NDK?

​ NDK全名Native Develop Kit,andriod本地开发工具,是Google开发的一套方便开发者在Android 平台上开发Native 代码的工具;

​ 使用NDK自带的工具,可快速对C/C++代码进行构建、编译和打包,最终生成动态/静态库供开发者使用,且不容易被反编译;

3、如何导入NDK与Cmake环境? 3.1在Setting的Android SDK中勾选以下配置;

在这里插入图片描述

3.2 因为Cmake要用到NDK,所以Android NDK location需要指定本地NDK路径;

在这里插入图片描述

4、如何在已有AS项目中导入Cmake? 4.1导入Cmake相关文件;

​ 路径可以自定义,这里选择的是"app/src/main/cpp/",其中CMakeLists.txt是Cmake的执行脚本, test-jni.c是Jni文件,用于编译生成so库; 在这里插入图片描述

4.2. app工程关联Cmake

​ 打开app目录下的build.gradle(见上图红框),添加以下语句,使AS工程关联上Cmake用于编译;

​ 参考网址: https://www.cnblogs.com/qcjd/p/9324903.html

android{ ... defaultConfig { ... externalNativeBuild { cmake { cppFlags "" // Passes optional arguments to CMake.//编译选项,与makefile类似 //arguments "-DANDROID_ARM_NEON=TRUE", "-DANDROID_TOOLCHAIN=clang" // Sets optional flags for the C compiler.预置C的宏 //cFlags "-D_EXAMPLE_C_FLAG1", "-D_EXAMPLE_C_FLAG2" // Sets a flag to enable format macro constants for the C++ compiler.预置C++的宏 //cppFlags "-D__STDC_FORMAT_MACROS" } } ndk {//编译生成哪个CPU平台的库 abiFilters 'armeabi-v7a','x86_64' // ARMv5——armeabi // ARMv7 ——armeabi-v7a // ARMv8——arm64- v8a // x86——x86 // MIPS ——mips // MIPS64——mips64 // x86_64——x86_64 } } ... externalNativeBuild { cmake { path file('src/main/cpp/CMakeLists.txt') //CMakeLists.txt存放路径 version "3.10.2" } } ... } 5、Cmake常用语法介绍 # For more information about using CMake with Android Studio, read the # documentation: https://d.android.com/studio/projects/add-native-code.html # Sets the minimum version of CMake required to build the native library. cmake_minimum_required(VERSION 3.4.1) project(NDK) ###############参考网址:https://www.cnblogs.com/qcjd/p/9324903.html # ==========================================语法知识(start)===================================== # 0=============================================== #1、 设置多文件目录---方法1: (常用) #1.1查找src/main/cpp目录下所有以*./c *.cpp文件并保存到DIR_SRCS变量里 file(GLOB DIR_SRCS “src/main/cpp/*.c” “src/main/cpp/*.cpp”) #1.2不同级目录下的指定 file(GLOB DIR_SRCS “../src2/main/cpp/*.c” “../src3/main/cpp/*.cpp”) #1.3如果cpp目录下还有别的子目录,但又不想每个子目录路径都制定过来,则可以用到递归查找 file(GLOB_RECURSE SRC_FILES "src/hello*")#注意:这里的目录不能有特殊字符,例如: #2、设置多文件目录---方法2:指定当前目录下的源文件,保存到变量中 aux_source_directory(. DIR_SRCS) #3、关联1或2中的DIR_SRCS变量,生成库 # # SHARED: 动态库 STATIC:静态库、 add_library(hello-jni SHARED ${DIR_SRCS}) # 制定生成目标(可忽略) add_executable(mathPowerDemo2 ${ALL_SRCS}) # =========================================== # 1.1、引入已有的预编译好的静态库 # StaticTest 可以随便起名字(原名:libStaticTest.a) # IMPORTED: 表示静态库是以导入的形式添加进来(预编译静态库) add_library(StaticTest STATIC IMPORTED) # 1.2、引入已有的预编译好的动态库 # SharedTest 可以随便起名字(原名:libSharedTest.so) # IMPORTED: 表示静态库是以导入的形式添加进来(预编译静态库) add_library(SharedTest SHARED IMPORTED) # 2.1、设置1.1/1.2中指定的动态库/静态库的导入路径 # 下面CMAKE_SOURCE_DIR 是系统预定义好的变量,代表当前CMakeLists.txt所在的目录 set_target_properties(StaticTest PROPERTIES IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/src/main/static/armeabi-v7a/libStaticTest.a) #下面${ANDROID_ABI}中的ANDROID_ABI应该指各个ABI版本的目录 # othermodule为库名称 set_target_properties(othermodule PROPERTIES IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/src/main/jniLibs/${ANDROID_ABI}/libothermodule.so) # 各个ABI版本 # ARMv5——armeabi # ARMv7 ——armeabi-v7a # ARMv8——arm64- v8a # x86——x86 # MIPS ——mips # MIPS64——mips64 # x86_64——x86_64 # 2.2、设置动态库的导入路径 # 下面CMAKE_SOURCE_DIR 是系统预定义好的变量,代表当前CMakeLists.txt所在的目录 set_target_properties(StaticTest PROPERTIES IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/src/main/static/armeabi-v7a/libSharedTest.so) # 3.1 额外头文件查找路径设置 相当于makefile中的-I include_directories(src/main/include)//本地或者外部库需要的头文件路径指定 # 3.2 使用其余CMakeLists.txt配置 # 额外引入src/main/subcmakelist目录的cmakelist add_subdirectory(src/main/subcmakelist) # 3.3 增加指定的宏定义 相当于-D add_definitions(-D_LINUX -D_ANDROID) # 4、配置动态库链接,生成native-lib动态库需要用到StaticTest log动态或者静态库 target_link_libraries( # Specifies the target library. native-lib # libTest.so 可以去掉lib与.so StaticTest SharedTest log ) # 动态库这样引入没有版本差异,如果像上面那样引入会有版本问题 # CMAKE_CXX_FLAGS 会传给c++编译器 # CMAKE_C_FLAGS 会传给c编译器 # CMAKE_SOURCE_DIR 的值是当前CMakelist.txt所在目录 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -L${CMAKE_SOURCE_DIR}/src/main/jniLibs/armeabi-v7a") # ===========================================语法知识(end)======================================== # ===========================================使用范本======================================== # Creates and names a library, sets it as either STATIC # or SHARED, and provides the relative paths to its source code. # You can define multiple libraries, and CMake builds them for you. # Gradle automatically packages shared libraries with your APK. # 配置so库信息 add_library( # Sets the name of the library. # 生成的so库名称,此处生成的so文件名称是libnative-lib.so native-lib # Sets the library as a shared library. # STATIC:静态库,是目标文件的归档文件,在链接其它目标的时候使用 # SHARED:动态库,会被动态链接,在运行时被加载 # MODULE:模块库,是不会被链接到其它目标中的插件,但是可能会在运行时使用dlopen-系列的函数动态链接 SHARED # Provides a relative path to your source file(s). # 资源文件,可以多个, # 资源路径是相对路径,相对于本CMakeLists.txt所在目录 src/maind/jni/XJni.c) # Searches for a specified prebuilt library and stores the path as a # variable. Because CMake includes system libraries in the search path by # default, you only need to specify the name of the public NDK library # you want to add. CMake verifies that the library exists before # completing its build. # 从系统查找依赖库 find_library( # Sets the name of the path variable. # android系统每个类型的库会存放一个特定的位置,而log库存放在log-lib中 log-lib # Specifies the name of the NDK library that # you want CMake to locate. # android系统在c环境下打log到logcat的库 log ) # Specifies libraries CMake should link to your target library. You # can link multiple libraries, such as libraries you define in this # build script, prebuilt third-party libraries, or system libraries. # 配置库的链接(依赖关系) target_link_libraries( # Specifies the target library. # 目标库 native-lib # Links the target library to the log library # included in the NDK. # 依赖于 ${log-lib} ) 6、简单写个JNI验证目标库是否生成可用 6.1在cpp目录下简单写个jni

在这里插入图片描述

6.2 点击make project(Ctrl+F9)后查看目标库是否生成

在这里插入图片描述

6.3 更多技术文章可关注本人公众号

在这里插入图片描述



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3